home *** CD-ROM | disk | FTP | other *** search
/ MacHack 2001 / MacHack 2001.toast / pc / The Hacks / 99 Bottles hack / MyUtils / MyStrings.p < prev   
Encoding:
Text File  |  2001-06-23  |  8.3 KB  |  288 lines

  1. unit MyStrings;
  2.  
  3. { Useful string management functions }
  4.  
  5. interface
  6.  
  7.     uses
  8.         AppleTalk, Processes, PPCToolbox, EPPC, Notification, AppleEvents, { All this to use the apple event manager in Convert.* ... }
  9.         TextUtils, Resources, {}
  10.         Assertions;
  11.  
  12.     const
  13.         kNumbersOnly = ['0'..'9', '.', 'e', 'E', '+', '-'];
  14.         kAutoNumDec = -99;
  15.  
  16.     function MyGetStr (resID, index, language: Integer): Str255;
  17.  
  18.     function MyReadStringLongInt (s: Str255): LongInt;
  19.     function MyReadStringReal (s: Str255): double;
  20.  
  21. { Substitute s1, s2, s3 and s4 for ^0, ^1, ^2 and ^3 in res }
  22.     procedure MyParamStr (var res: Str255; s1, s2, s3, s4: Str255);
  23.  
  24. { Convertir un réel en string approprié }
  25. { Passer kAutoNumDec en nbDecMax pour laisser le Mac faire la conversion }
  26. { Passer un nombre < 0 pour faire une conversion pour affichage à l'écran et }
  27. { un nombre >= 0 pour forcer le nombre de décimales exact. }
  28. { L'affichage à l'écran peut réduire le nombre de décimales présenté afin de ne }
  29. { pas présenter trop de chiffres à l'écran. Patch 23/08/99 PhC }
  30.     function GedoubleString (val: double; nbDecMax: Integer): Str255; { nombre de décimales }
  31. { Une procédure d'appel à la fonction GedoubleString pour satisfaire le langage C... }
  32.     procedure GedoubleStringProc (val: double; nbDecMax: Integer; var s: Str255);
  33.  
  34. { Procédures permettant d'échanger entre un array de caractères et un Str255 }    
  35.     procedure MyCharHandleToString(c: Handle; var s: Str255);
  36.     procedure MyStringToCharHandle(s: Str255; var c: Handle);
  37.  
  38. { Fonction qui retourne le nom de la machine tel qu'entré par l'utilisateur dans le tdb Partage de Fichiers }
  39.     function GetMachineName: Str255;
  40.  
  41. implementation
  42.  
  43.     function MyGetStr (resID, index, language: Integer): Str255;
  44.         var
  45.             s: Str255;
  46.     begin
  47.         GetIndString(s, resID + language, index);
  48.         if ResError <> noErr then begin
  49.             MyDebugStr('Non-localized string, OK to continue');
  50.             GetIndString(s, resID, index);
  51.         end;
  52.         if ResError <> noErr then
  53.             MyDebugStr('String not found, returning empty string');
  54.         MyGetStr := s;
  55.     end; { MyGetStr }
  56.  
  57.     function MyReadStringLongInt (s: Str255): LongInt;
  58.         var
  59.             result: LongInt;
  60.     begin
  61.         result := 0;
  62.         StringToNum(s, result);
  63.         MyReadStringLongInt := result;
  64.     end; { MyReadStringLongInt }
  65.  
  66. { These two functions are adapted from a tip in Nov. 98 MacTech by Stephen L. Reid }
  67. { <sread@ti.com> to leave it to the Apple Event Manager to do all the dirty work, }
  68. { avoiding ReadString and eventually StringOf. ConvertDoubleToString is by SLR and }
  69. { ConvertStringToDouble is by PhC. }
  70.     function ConvertDoubleToString (inValue: double; var resultStr: Str255): OSErr;
  71.         var
  72.             theErr: OSErr;
  73.             outResult: AEDesc;
  74.             l: LongInt;
  75.     begin
  76.         theErr := AECoercePtr(typeFloat, @inValue, Size(SizeOf(double)), typeChar, outResult); { input data type - 'doub' }
  77.  { pointer to input data }
  78.  { size of input data }
  79.  { desired 'want' type is character }
  80.  { pointer to AEDesc for output data }
  81.         if (theErr = noErr) then begin
  82.             l := GetHandleSize(outResult.dataHandle);
  83.             if l > 0 then begin
  84.                 if l > 254 then
  85.                     l := 254;
  86. {$push}
  87. {$R-}
  88.                 BlockMove(outResult.dataHandle^, @resultStr[1], l); { no need to hlock, this tb trap doesn't move memory! }
  89.                 resultStr[0] := Chr(l);
  90. {$pop}
  91.             end;
  92.             if (noErr = AEDisposeDesc(outResult)) then
  93.                 ; { ignore error in this case }
  94.         end;
  95.         ConvertDoubleToString := theErr;
  96.     end; { ConvertDoubleToString }
  97.  
  98.     function ConvertStringToDouble (inStr: Str255; var resultValue: double): OSErr;
  99.         var
  100.             theErr: OSErr;
  101.             outResult: AEDesc;
  102.             l: LongInt;
  103.     begin
  104.         theErr := AECoercePtr(typeChar, @inStr[1], Size(Length(inStr)), typeFloat, outResult); { input data type - character }
  105.  { pointer to input data }
  106.  { size of input data }
  107.  { desired 'want' type is 'doub' }
  108.  { pointer to AEDesc for output data }
  109.         if (theErr = noErr) then begin
  110.             l := GetHandleSize(outResult.dataHandle);
  111.             if l > 0 then begin
  112.                 BlockMove(outResult.dataHandle^, @resultValue, l);
  113.             end;
  114.             if (noErr = AEDisposeDesc(outResult)) then
  115.                 ; { ignore error in this case }
  116.         end;
  117.         ConvertStringToDouble := theErr;
  118.     end; { ConvertStringToDouble }
  119.  
  120.     function MyReadStringReal (s: Str255): double;
  121.         var
  122.             result: double;
  123.             i: LongInt;
  124.     begin
  125.     { Added this check for non-numerics to prevent some strange crashes in the AE Manager... }
  126.         if Length(s) > 0 then
  127.             for i := 1 to Length(s) do
  128.                 if not (s[i] in kNumbersOnly) then { remove character at position i }
  129.                     s[i] := ' ';
  130.         if ConvertStringToDouble(s, result) <> noErr then
  131.             result := -999;
  132.         MyReadStringReal := result;
  133.     end; { MyReadStringReal }
  134.  
  135. {$ifc false}
  136. { A crude procedure that would need to be localized; what it does is strip }
  137. { all non-numeric characters from a string and reads the result using ReadString. }
  138. { I can't use ReadString directly because it would crash if it encountered a non- }
  139. { numeric character... }
  140.     function MyReadStringReal (s: Str255): double;
  141.         var
  142.             result: double;
  143.             i: Integer;
  144.             eCount, mantCount, expCount: Integer;
  145.     begin
  146.         result := 0;
  147.         if Length(s) > 0 then begin
  148.             for i := Length(s) downto 1 do begin
  149.                 if not (s[i] in kNumbersOnly) then begin { remove character at position i }
  150.                     Delete(s, i, 1);
  151.                 end;
  152.             end;
  153.             {$ifc false}
  154.             if Length(s) > 0 then begin { take care of e's and +/- }
  155.                 eCount := 0;
  156.                 for i := 1 to Length(s) do
  157.                     if (s[i] in ['e', 'E']) then begin
  158.                         eCount := eCount + 1;
  159.                         s[i] := 'E'; { put in uppercase }
  160.                     end;
  161.                 if eCount > 0 then begin
  162.                     if eCount > 1 then { remove extra e's }
  163.                         for i := Length(s) downto 1 do
  164.                             if (s[i] in ['e', 'E']) and (eCount > 1) then begin
  165.                                 Delete(s, i, 1);
  166.                                 eCount := eCount - 1;
  167.                             end; { if }
  168.                     { here, eCount should be = 1. Check if there is a number before and after }
  169.                     mantCount := 0;
  170.                     for i := 1 to Pos('E', s) do
  171.                         if s[i] in ['0'..'9'] then
  172.                             mantCount := mantCount + 1;
  173.                     expCount := 0;
  174.                     for i := Pos('E', s) to Length(s) do
  175.                         if s[i] in ['0'..'9'] then
  176.                             expCount := expCount + 1;
  177.                     if (mantCount = 0) and (expCount = 0) then { remove 'E' if no mantissa and exponent }
  178.                         Delete(s, Pos('E', s), 1);
  179.                 end;
  180.             end;
  181.             {$endc}
  182.             if Length(s) > 0 then
  183.                 ReadString(s, result);
  184.         end;
  185.  
  186.         MyReadStringReal := result;
  187.     end; { MyReadStringReal }
  188. {$endc}
  189.  
  190.     procedure MyParamStr;
  191.         procedure SubstituteParam (paramStr, subsStr: Str255);
  192.             var
  193.                 p: Integer;
  194.         begin
  195.             p := Pos(paramStr, res);
  196.             if p > 0 then
  197.                 Delete(res, p, 2);
  198.             Insert(subsStr, res, p);
  199.         end; { SubstituteParam }
  200.     begin
  201.         SubstituteParam('^3', s4);
  202.         SubstituteParam('^2', s3);
  203.         SubstituteParam('^1', s2);
  204.         SubstituteParam('^0', s1);
  205.     end; { MyParamStr }
  206.  
  207.     function GedoubleString (val: double; nbDecMax: Integer): Str255;
  208.         var
  209.             abv: double;
  210.             s: Str255;
  211.     begin
  212.         if nbDecMax = kAutoNumDec then begin { pas de conversion demandée, utiliser le MacOS }
  213.             if ConvertDoubleToString(val, s) <> noErr then
  214.                 s := '???';
  215.         end
  216.         else if nbDecMax < 0 then begin { conversion pour affichage à l'écran }
  217.             nbDecMax := -nbDecMax;
  218.             abv := Abs(val);
  219.             if abv > 1e4 then
  220.                 if abv < 1E+300 then
  221.                     s := StringOf(val)
  222.                 else begin
  223.                     if val > 0 then
  224.                         s := '+INF'
  225.                     else
  226.                         s := '-INF';
  227.                 end
  228.             else begin
  229.                 if abv > 1e1 then
  230.                     nbDecMax := nbDecMax - 1
  231.                 else if abv > 1e2 then
  232.                     nbDecMax := nbDecMax - 1
  233.                 else if abv > 1e3 then
  234.                     nbDecMax := nbDecMax - 1;
  235.                 s := StringOf(val : nbDecMax + 2 : nbDecMax);
  236.             end; { else }
  237.         end { else if }
  238.         else
  239. {$push}
  240. {$R-}
  241.             s := StringOf(val : nbDecMax + 2 : nbDecMax);
  242. {$pop}
  243.  
  244.         GedoubleString := s;
  245.  
  246.     end; { GedoubleString }
  247.  
  248.     procedure GedoubleStringProc (val: double; nbDecMax: Integer; var s: Str255);
  249.     begin
  250.         s := GedoubleString(val, nbDecMax);
  251.     end; { GedoubleStringProc }
  252.  
  253.  
  254.     procedure MyCharHandleToString(c: Handle; var s: Str255);
  255.     var
  256.         l: LongInt;
  257.     begin
  258.         l := GetHandleSize(c);
  259.         if (l > 254) then
  260.             l := 254;
  261.         BlockMoveData(c^, @s[1], l);
  262. {$push}
  263. {$R-}
  264.         s[0] := Chr(l);
  265. {$pop}
  266.     end; { MyCharHandleToString }
  267.     
  268.     procedure MyStringToCharHandle(s: Str255; var c: Handle);
  269.     var
  270.         l: LongInt;
  271.     begin
  272.         l := Length(s);
  273.         c := NewHandleClear(l);
  274.         BlockMoveData(@s[1], c^, l);
  275.     end; { MyStringToCharHandle }
  276.  
  277.     function GetMachineName: Str255;
  278.     var
  279.         macNameH: StringHandle;
  280.     begin
  281.         macNameH := GetString(-16413); { Machine name id in the System file }
  282.         if (macNameH <> nil) then
  283.             GetMachineName := macNameH^^
  284.         else
  285.             GetMachineName := '';
  286.     end; { GetMachineName }
  287.  
  288. end. { MyStrings }